package org.lonetree.tc.core;

import java.util.Set;
import java.util.HashSet;
import org.lonetree.tc.core.id.NaturaldentifiableItem;
import org.lonetree.tc.core.id.ValidatedIdentifier;

/**
 * Business class representing university courses in the system.
 * 
 * All interfaces between different system components should use objects of this
 * class to pass information about courses.
 */
public final class Course extends NaturaldentifiableItem{

	private String title;
	private Set<Section> sections;
	private Set<CourseComment> comments;
	
	protected Course(CourseId courseId){
		this(courseId, null, null, null);
	}
	
	protected Course(CourseId courseId, String title, Set<Section> sections, Set<CourseComment> comments){
		super(courseId);
		
		this.title = title;
		this.sections = sections;
		this.comments = comments;
		
		if(sections == null)
			this.sections = new HashSet<Section>();
		
		if(comments == null)
			this.comments = new HashSet<CourseComment>();
	}
	
	/**
	 * Get the CourseId identifying the course.
	 *
	 * @return CourseId
	 */
	public CourseId getCourseId(){
		return (CourseId)getIdentifier();
	}
	
	/**
	 * Get the title of the course.
	 *
	 * @return title
	 */
	public String getTitle(){
		return title;
	}
	
	/**
	 * Get the sections for the course.
	 *
	 * @return section Set
	 */
	public Set<Section> getSections(){
		return sections;
	}
	
	/**
	 * Get the comments for the course.
	 *
	 * @return comment Set
	 */
	public Set<CourseComment> getComments(){
		return comments;
	}
	
	/**
	 * Set the title for the course.
	 *
	 * @param title - the new title
	 */
	public void setTitle(String title){
		this.title = title;
	}
	
	protected String getIdentifierType(){
		return "courseId";
	}
	
	/**
	 * ValidatedIdentifier representing a course ID (e.g. CPSC410, ENGL112,
	 * etc). CourseIds are the unique identifiers for all Course objects.
	 */
	public static class CourseId extends ValidatedIdentifier{
		
		/**
		 * Create a CourseId encapsulating the passed departmentId and
		 * courseNumber.
		 *
		 * @param departmentId - the 4-letter ID representing a university
		 * 						 department (e.g. CPSC or ENGL)
		 * @param courseNumber - the 3-number ID of a course offered by a
		 * 						 certain department (e.g. 410, 112)
		 * @throws ValidationException if the departmentId is not 4 characters
		 * 							   long or if the courseNumber is greater
		 * 							   than 999 (thus making it longer than 3
		 * 							   numbers)
		 */
		public CourseId(String departmentId, short courseNumber) throws ValidationException{
			super(departmentId + courseNumber);
		}
		
		/**
		 * Creates a CourseId encapsulating the passed courseId.
		 *
		 * @param courseId - the 7-character ID representing the full identifier
		 * 					 for a university course (e.g. CPSC313, ENGL112)
		 * @throws ValidationException if the first four characters are not
		 * 							   letters or the last 3 characters are not
		 * 							   numbers (or if the length of the String
		 * 							   is not exactly 7)
		 */
		public CourseId(String courseId) throws ValidationException{
			super(courseId);
		}

		@Override
		protected String validateAndFix(String identifier) throws ValidationException{
			validateLength(identifier, 7, "courseId");
			try{
				String departmentId = identifier.substring(0, 4).trim();
				validateLength(departmentId, 4, "departmentId");
				String courseId = identifier.substring(4);
				Short.parseShort(courseId);
				return departmentId.toUpperCase() + courseId;
			}
			catch(Exception e){
				throw new ValidationException(e);
			}
		}
		
		/**
		 * Get the String representation of the course ID.
		 *
		 * @return course ID
		 */
		public String getCourseIdString(){
			return getIdentifierString();
		}
		
		/**
		 * Get the String representation of the department offering the course.
		 *
		 * @return department
		 */
		public String getDepartment(){
			return getCourseIdString().substring(0, 4);
		}
		
		/**
		 * Get the String representation of the course number.
		 *
		 * @return course number
		 */
		public String getNumber(){
			return getCourseIdString().substring(4,7);
		}
	}
}
